
#include "Conf.h"
#include <experimental/filesystem>
#include "myLog.h"
#include "Ini.h"



// namespace begin.
namespace Conf 
{

using namespace std;

ConfItem *currentConf() 
{
    static ConfItem singleton;

    return &singleton;
}

uint16_t convertDevType2Integer(const string &typeStr) 
{
    auto value = DEV_TYPE_UNKNOWN;
    if ("SXD" == typeStr) 
    {
        value = DEV_TYPE_SXD;
    }

    return value;
}

Result loadConf(const string &path) 
{
    auto conf = currentConf();

    int res = 0;
    char buffer[100];
    unsigned char tmp;
    if (false == experimental::filesystem::is_regular_file(path)) 
    {
        auto err = Result::create(ErrorKind::FileNotExist);
        auto msg = string("file path: '") + path + "'";
        err.appendInfo(msg);

        return err;
    }
    auto confPath = path.c_str();
    auto fileName = "the Conf.ini file' is empty";
    memset(buffer,'\0',sizeof(buffer));
    res = readStringValue((char *)"DeviceType",(char *)"type",buffer,confPath);
    
    tmp = (unsigned char)(strchr(buffer, '\n') - buffer);
    conf->type = (tmp > 0)?strndup(buffer, tmp):strdup(buffer);
    conf->typeValue = convertDevType2Integer(conf->type);
    if (res != 0 || true == conf->type.empty()) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The type in the Name title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    //debug获取使用模式，直接发不解压
    memset(buffer,'\0',sizeof(buffer));
    int m_debug = readIntValue((char *)"DeviceType",(char *)"debug",confPath);
    if(m_debug > 0) {
        conf->debug = true;
    }
    //调度插件分发，配合DEBUG模式使用
    memset(buffer,'\0',sizeof(buffer));
    res = readStringValue((char *)"DeviceType",(char *)"shell",buffer,confPath);
    
    tmp = (unsigned char)(strchr(buffer, '\n') - buffer);
    conf->shell = (tmp > 0)?strndup(buffer, tmp):strdup(buffer);
    if (conf->debug && (res != 0 || true == conf->shell.empty())) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The description in the Name title of '") + fileName;
        err.appendInfo(msg);
        
        return err;
        
    }

    //tcp
    memset(buffer,'\0',sizeof(buffer));
    conf->tcp.port = readIntValue((char *)"tcp",(char *)"port",confPath);
    if (conf->tcp.port <= 0) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The port in the application title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    memset(buffer,'\0',sizeof(buffer));
    conf->tcp.headerSize = readIntValue((char *)"tcp",(char *)"headerSize",confPath);
    if (conf->tcp.headerSize <= 0) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The headerSize in the application title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    //udp
    memset(buffer,'\0',sizeof(buffer));
    conf->udp.port = readIntValue((char *)"udp",(char *)"port",confPath);
    if (conf->udp.port <= 0) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The port in the application title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    memset(buffer,'\0',sizeof(buffer));
    conf->udp.headerSize = readIntValue((char *)"udp",(char *)"headerSize",confPath);
    if (conf->udp.headerSize <= 0) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The headerSize in the application title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    memset(buffer,'\0',sizeof(buffer));
    conf->udp.chunkSize = readIntValue((char *)"udp",(char *)"chunkSize",confPath);
    if (conf->udp.chunkSize <= 0) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The chunkSize in the application title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    memset(buffer,'\0',sizeof(buffer));
    conf->udp.confirmMagic = readIntValue((char *)"udp",(char *)"confirmMagic",confPath);
    if (conf->udp.confirmMagic <= 0) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The confirmMagic in the application title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    //ramfs
    memset(buffer,'\0',sizeof(buffer));
    conf->ramfs.maxSize = readIntValue((char *)"ramfs",(char *)"maxSize",confPath);
    if (conf->ramfs.maxSize <= 0) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The maxSize in the application title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    memset(buffer,'\0',sizeof(buffer));
    res = readStringValue((char *)"ramfs",(char *)"mountPoint",buffer,confPath);
    
    tmp = (unsigned char)(strchr(buffer, '\n') - buffer);
    conf->ramfs.mountPoint = (tmp > 0)?strndup(buffer, tmp):strdup(buffer);
    if (res != 0 || true == conf->ramfs.mountPoint.empty()) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The mountPoint in the Name title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    memset(buffer,'\0',sizeof(buffer));
    res = readStringValue((char *)"ramfs",(char *)"description",buffer,confPath);
    
    tmp = (unsigned char)(strchr(buffer, '\n') - buffer);
    conf->ramfs.description = (tmp > 0)?strndup(buffer, tmp):strdup(buffer);
    if (res != 0 || true == conf->ramfs.description.empty()) 
    {
        auto err = Result::create(ErrorKind::InvalidData);
        auto msg = string("The description in the Name title of '") + fileName;
        err.appendInfo(msg);

        return err;
    }

    return Result();
}





}  // namespace end.
